<template >
    <a-sub-menu  key="sub5" :class="isChosen == true ? 'chosen' : 'false'">
        <template #title>工具箱</template>
        <a-menu-item key="setting:11" @click="handleLine">测量距离</a-menu-item>
        <a-menu-item key="setting:12" @click="handleArea">测量面积</a-menu-item>
        <a-menu-item key="setting:13" @click="handlePic">导出图片</a-menu-item>
        <a-menu-item key="setting:14" @click="handleClear">关闭测量</a-menu-item>
    </a-sub-menu>
</template>
<script setup>
import { useMapStore } from "stores/mapStore.js";
/* store数据响应式 */
import { storeToRefs } from "pinia";
import { ref } from "vue";
/* 实例化useMapStore */
const mapStore = useMapStore();
/* 解构并响应式 */
const { map } = storeToRefs(mapStore);
let draw = ref(null)
const source = ref(null)
var pointermove
var sketch;
const helpTooltipElement = ref(null)
var helpTooltip;
const measureTooltipElement = ref(null)
var measureTooltip;
var continuePolygonMsg = "单击开始绘制，双击结束面积测量";
var continueLineMsg = "单击开始绘制，双击结束距离测量";
let isChosen = ref(false);
const toolBoxLayer = ref(null)
function handleLine() {
    isChosen = true
    let measuretype = "line";
    Meassurement(measuretype);
}
function handleArea() {
    isChosen = true
    let measuretype = "area";
    Meassurement(measuretype);
}
function handlePic() {
    isChosen = true
    exportMap();
}
function handleClear() {
    isChosen = true
    ccremove();

}
// 激活测量
function Meassurement(measuretype) {
    // console.log("激活测量");
    if (source.value == null) {
        //加载测量的绘制矢量层
        source.value = new ol.source.Vector(); //图层数据源
    }
    if (toolBoxLayer.value == null) {
        toolBoxLayer.value = new ol.layer.Vector({
            source: source.value,
            style: new ol.style.Style({
                //图层样式
                fill: new ol.style.Fill({
                    color: "rgba(255, 30, 18, 0.2)", //填充颜色
                }),
                stroke: new ol.style.Stroke({
                    color: "blue", //边框颜色
                    width: 5, // 边框宽度
                }),
                image: new ol.style.Circle({
                    radius: 7,
                    fill: new ol.style.Fill({
                        color: "blue",
                    }),
                }),
            }),
        });
        map.value.addLayer(toolBoxLayer.value);
    }
    /* 首先清除画笔 */
    map.value.removeInteraction(draw.value);
    /**
     * 鼠标移动事件处理函数
     * @param {ol.MapBrowserEvent} evt
     */
    var pointerMoveHandler = function (evt) {
        if (evt.dragging) {
            return;
        }
        /** @type {string} */
        var helpMsg = "点击开始绘制"; //当前默认提示信息
        //判断绘制几何类型设置相应的帮助提示信息
        if (sketch) {
            var geom = sketch.getGeometry();
            if (geom instanceof ol.geom.Polygon) {
                helpMsg = continuePolygonMsg; //绘制多边形时提示相应内容
            } else if (geom instanceof ol.geom.LineString) {
                helpMsg = continueLineMsg; //绘制线时提示相应内容
            }
        }
        helpTooltipElement.value.innerHTML = helpMsg; //将提示信息设置到对话框中显示
        helpTooltipElement.value.style.color = "red";
        helpTooltip.setPosition(evt.coordinate); //设置帮助提示框的位置
        // document.getElementsByName(helpTooltipElement.value).removeClass("hidden"); //移除帮助提示框的隐藏样式进行显示
    };
    ol.Observable.unByKey(pointermove); //移除点击事件
    // /* 清除绑定的事件 */
    // map.value.un("pointermove", () => {
    //     console.log("jieble");
    // });
    pointermove = map.value.on("pointermove", pointerMoveHandler); //地图容器绑定鼠标移动事件，动态显示帮助提示框内容
    // var geodesicCheckbox = document.getElementById("geodesic"); //测地学方式对象
    // global so we can remove it later
    var type = measuretype == "area" ? "Polygon" : "LineString";
    draw.value = new ol.interaction.Draw({
        source: source.value, //测量绘制层数据源
        type: /** @type {ol.geom.GeometryType} */ (type), //几何图形类型
        style: new ol.style.Style({
            //绘制几何图形的样式
            fill: new ol.style.Fill({
                color: "rgba(255, 255, 255, 0.1)",
            }),
            stroke: new ol.style.Stroke({
                color: "dodgerblue",
                lineDash: [10, 10],
                width: 2,
            }),
            image: new ol.style.Circle({
                radius: 5,
                stroke: new ol.style.Stroke({
                    color: "rgba(255, 30, 0, 0.7)",
                }),
                fill: new ol.style.Fill({
                    color: "rgba(255, 255, 255, 0.2)",
                }),
            }),
        }),
    });
    map.value.addInteraction(draw.value);
    createMeasureTooltip(); //创建测量工具提示框
    createHelpTooltip(); //创建帮助提示框

    var listener;
    //绑定交互绘制工具开始绘制的事件
    draw.value.on(
        "drawstart",
        function (evt) {
            // set sketch
            sketch = evt.feature; //绘制的要素

            /** @type {ol.Coordinate|undefined} */
            var tooltipCoord = evt.coordinate; // 绘制的坐标
            //绑定change事件，根据绘制几何类型得到测量长度值或面积值，并将其设置到测量工具提示框中显示
            listener = sketch.getGeometry().on("change", function (evt) {
                var geom = evt.target; //绘制几何要素
                var output;
                if (geom instanceof ol.geom.Polygon) {
                    output = formatArea(/** @type {ol.geom.Polygon} */(geom)); //面积值
                    tooltipCoord = geom.getInteriorPoint().getCoordinates(); //坐标
                } else if (geom instanceof ol.geom.LineString) {
                    output = formatLength(/** @type {ol.geom.LineString} */(geom)); //长度值
                    tooltipCoord = geom.getLastCoordinate(); //坐标
                }
                measureTooltipElement.value.innerHTML = output; //将测量值设置到测量工具提示框中显示
                measureTooltipElement.value.style.color = "red";

                measureTooltip.setPosition(tooltipCoord); //设置测量工具提示框的显示位置
            });
        },
        this
    );
    //绑定交互绘制工具结束绘制的事件
    draw.value.on(
        "drawend",
        function (evt) {
            measureTooltipElement.value.className = "tooltip tooltip-static"; //设置测量提示框的样式
            measureTooltipElement.value.style.background = "#409eff";
            measureTooltipElement.value.style.color = "#fff";
            measureTooltipElement.value.style.fontSize = "16px";
            measureTooltipElement.value.style.padding = "10px";
            measureTooltip.setOffset([0, -7]);
            sketch = null; //置空当前绘制的要素对象
            // unset tooltip so that a new one can be created
            measureTooltipElement.value = null; //置空测量工具提示框对象
            createMeasureTooltip(); //重新创建一个测试工具提示框显示结果
            ol.Observable.unByKey(listener);
        },
        this
    );

    /**
     *创建一个新的帮助提示框（tooltip）
     */
    function createHelpTooltip() {
        if (helpTooltipElement.value) {
            helpTooltipElement.value.parentNode.removeChild(helpTooltipElement.value);
        }
        helpTooltipElement.value = document.createElement("div");
        helpTooltipElement.value.className = "tooltip hidden";
        helpTooltip = new ol.Overlay({
            element: helpTooltipElement.value,
            offset: [15, 0],
            positioning: "center-left",
        });
        map.value.addOverlay(helpTooltip);
    }
    /**
     *创建一个新的测量工具提示框（tooltip）
     */
    function createMeasureTooltip() {
        // console.log(333);
        // console.log(measureTooltipElement.value);
        if (measureTooltipElement.value) {
            measureTooltipElement.value.parentNode.removeChild(measureTooltipElement.value);
        }
        measureTooltipElement.value = document.createElement("div");
        measureTooltipElement.value.className = "tooltip tooltip-measure";
        measureTooltip = new ol.Overlay({
            element: measureTooltipElement.value,
            offset: [0, -15],
            positioning: "bottom-center",
        });
        map.value.addOverlay(measureTooltip);
    }
    /**
     * 测量长度输出
     * @param {ol.geom.LineString} line
     * @return {string}
     */
    var formatLength = function (line) {
        var length;
        var sphere = new ol.Sphere();
        //若使用测地学方法测量
        var sourceProj = map.value.getView().getProjection(); //地图数据源投影坐标系
        length = sphere.getLength(line, {
            projection: sourceProj,
            radius: 6378137,
        });
        // length = Math.round(line.getLength() * 100) / 100; //直接得到线的长度
        var output;
        if (length > 100) {
            output = Math.round((length / 1000) * 100) / 100 + " " + "km"; //换算成KM单位
        } else {
            output = Math.round(length * 100) / 100 + " " + "m"; //m为单位
        }
        return output; //返回线的长度
    };
    /**
     * 测量面积输出
     * @param {ol.geom.Polygon} polygon
     * @return {string}
     */
    var formatArea = function (polygon) {
        var area;
        var sphere = new ol.Sphere();
        //若使用测地学方法测量
        var sourceProj = map.value.getView().getProjection(); //地图数据源投影坐标系
        var geom = /** @type {ol.geom.Polygon} */ (
            polygon.clone().transform(sourceProj, "EPSG:4326")
        ); //将多边形要素坐标系投影为EPSG:4326
        area = Math.abs(
            sphere.getArea(geom, { projection: sourceProj, radius: 6378137 })
        ); //获取面积
        // area = polygon.getArea(); //直接获取多边形的面积
        var output;
        if (area > 10000) {
            output =
                Math.round((area / 1000000) * 100) / 100 + " " + "km<sup>2</sup>"; //换算成KM单位
        } else {
            output = Math.round(area * 100) / 100 + " " + "m<sup>2</sup>"; //m为单位
        }
        return output; //返回多边形的面积
    };
}
function ccremove() {
    ol.Observable.unByKey(pointermove); //移除点击事件
    // /* 清除绑定的事件 */
    // map.value.un("pointermove", () => {
    //     console.log("jieble");
    // });
    // console.log('清除了');
    // console.log(map.value.getLayers());
    map.value.removeInteraction(draw.value);//清除画笔
    /* 清除生成的元素 */
    var paras = document.getElementsByClassName(
        "tooltip tooltip-static"
    );
    for (var i = paras.length; i >= 0; i--) {
        //删除元素 元素.parentNode.removeChild(元素);
        if (paras[i] != null) paras[i].parentNode.removeChild(paras[i]);
    }
    var parasHidden = document.getElementsByClassName(
        "tooltip hidden"
    );
    for (var i = paras.length; i >= 0; i--) {
        //删除元素 元素.parentNode.removeChild(元素);
        if (parasHidden[i] != null) parasHidden[i].parentNode.removeChild(parasHidden[i]);
    }

    /* 清除source和layer */
    if (source.value) {
        source.value.clear();
    }
    /* 重置生成的元素的状态 */
    measureTooltipElement.value = null
    helpTooltipElement.value = null
    /* 重置图层的状态 */
    source.value = null
    toolBoxLayer.value = null
    /* 清除图层 */
    map.value.removeLayer(toolBoxLayer.value)
}
/* 下载地图 */
function exportMap() {
    map.value.once("postcompose", function (event) {
        let canvas = event.context.canvas;
        // console.log(canvas);
        canvas.toBlob(function (blob) {
            // console.log(blob);
            saveAs(blob, "map.png");
        });
    });
    map.value.renderSync();
}
</script>
<style scoped>
.ol-tooltip {
    position: relative;
    background: rgba(0, 0, 0, 0.5);
    border-radius: 4px;
    color: white;
    padding: 4px 8px;
    opacity: 0.7;
    white-space: nowrap;
    font-size: 12px;
    cursor: default;
    user-select: none;
}

.ol-tooltip-measure {
    opacity: 1;
    font-weight: bold;
}

.ol-tooltip-static {
    background-color: #ffcc33;
    color: black;
    border: 1px solid white;
}

.ol-tooltip-measure:before,
.ol-tooltip-static:before {
    border-top: 6px solid rgba(0, 0, 0, 0.5);
    border-right: 6px solid transparent;
    border-left: 6px solid transparent;
    content: "";
    position: absolute;
    bottom: -6px;
    margin-left: -7px;
    left: 50%;
}

.ol-tooltip-static:before {
    border-top-color: #ffcc33;
}
</style>
